package com.yh.interceptor;

import com.yh.anno.LoginAuthentication;
import com.yh.utils.Constants;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.ObjectUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

/**
 * 身份验证拦截器 拦截未登录的用户
 *
 * @author yuhuan
 * @date 2022/01/13
 */
public class AuthenticationInterceptor implements HandlerInterceptor {
    /**
     * 日志
     */
    private final Logger logger = Logger.getLogger(AuthenticationInterceptor.class);

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
        if (IsInterceptorToPreHandle.isInterceptor(handler, LoginAuthentication.class)) {
            // 获取用户信息
            String token = request.getHeader("token");
            if (!ObjectUtils.isEmpty(token)) {
                try {
                    token = URLDecoder.decode(token, "UTF-8");
                    // 判断用户是否登录
                    boolean hasUserDataInRedis = hasUserDataInRedis(token);
                    if (hasUserDataInRedis) {
                        return true;
                    }
                } catch (UnsupportedEncodingException e) {
                    logger.warn(">>>>> 进行用户的身份验证时，发生信息提取异常" + e.getMessage());
                }
            }
            // 将请求拦截到登录服务器
            request.getRequestDispatcher("/api/login/expired/server").forward(request, response);
            return false;
        }
        return true;
    }

    /**
     * 查看用户信息在缓存中是否已经存在
     */
    private Boolean hasUserDataInRedis(String userId) {
        Boolean hasKey = redisTemplate.hasKey(createUserIdInRedis(userId));
        return hasKey;
    }

    /**
     * 生成用户在缓存中的KEY
     */
    public String createUserIdInRedis(String userId) {
        return Constants.LoginData.LOGIN_DATA_PREFIX_KEY + ":" + userId;
    }
}
